import Vue from 'vue'

/**
 * 根据菜单node 找到菜单的类型
 * @param menus
 * @param node
 */
export function findMenuType (menus, name) {
  let typeName = []
  menus.filter(a => a.nodes.length > 0).forEach(b => {
    b.nodes.forEach(c => { // 二级目录
      if (c.nodes.length > 0) {
        c.nodes.forEach(d => { // 三级目录
          if (d.name === name) {
            typeName.push(d.type)
          }
        })
      } else {
        if (c.name === name) {
          typeName.push(c.type)
        }
      }
    })
  })
  return typeName
}

/**
 * 根据菜单name 找到直接父节点
 * @param menus
 * @param node
 */
export function findMenuParent (menus, name) {
  let parentName = ''
  menus.filter(a => a.nodes.length > 0).forEach(b => {
    b.nodes.forEach(c => { // 二级目录
      if (c.nodes.length > 0) {
        c.nodes.forEach(d => { // 三级目录
          if (d.name === name) {
            parentName = c.name
          }
        })
      } else {
        if (c.name === name) {
          parentName = b.name
        }
      }
    })
  })
  return parentName
}

// 密码校验
function validateKey(password) {
  // 横向穷举
  /* eslint-disable */
  let zxsz = "qwertyuiop[]|@asdfghjkl;'@zxcvbnm,./@`1234567890-=@"
  // 纵向穷举
  var dxsz = "1qaz@2wsx@3edc@4rfv@5tgb@6yhn@7ujm@8ik,@9ol.@0p;/@"
  if (validateKeyXh(zxsz, password)) {
    return true
  }
  if (validateKeyXh(dxsz, password)) {
    return true
  }
  return false
}

function validateKeyXh(keysz, password) {
  let zxlen = keysz.length - 1
  for(let i = 0; i < zxlen; i++) {
    let a = (keysz.charAt(i) + keysz.charAt(i + 1) + keysz.charAt(i + 2) + keysz.charAt(i + 3)).toLowerCase()
    let b = (keysz.charAt(zxlen - i) + keysz.charAt(zxlen - 1 - i) + keysz.charAt(zxlen - 2 - i) + keysz.charAt(zxlen - 3 - i)).toLowerCase()
    let c = password.toLowerCase()
    let wReplace = c.replace(/~/g, '`').replace(/!/g, '1').replace(/@/g, '2').replace(/#/g, '3').replace(/\$/g, '4')
      .replace(/%/g, '5').replace(/\^/g, '6').replace(/&/g, '7').replace(/\*/g, '8').replace(/\(/g, '9')
      .replace(/\)/g, '0').replace(/\_/g, '-').replace(/\+/g, '=').replace(/{/g, '[').replace(/}/g, ']')
      .replace(/\\/g, '|').replace(/:/g, ';').replace(/"/g, '\'').replace(/</g, ',').replace(/>/g, '.')
      .replace(/\?/g, '/')
    if (a.indexOf('@') === -1) {
      if(wReplace.indexOf(a) != -1) {
        return true
      }
    }
    if (b.indexOf('@') === -1) {
      if(wReplace.indexOf(b) != -1) {
        return true
      }
    }
  }
  return false
}

// 全局校验特殊字符 <>%/\'"
export function  checkSpecialString (rule, value, callback) {
  if (!rule.required && !value) {
    callback()
  } else {
    if (!value) {
      return callback(new Error('不能为空'));
    }
    // 口令应包括数字、小写字母、大写字母、特殊符号4类中至少3类
    let reg =  new RegExp("[<>%/\'\"]")
    if (reg.test(value)) {
      return callback(new Error('不能含有特数字符'))
    }
    callback()
  }
}

export function  newPasswordCheck (rule, value, callback) {
  if (!rule.required && !value) {
    callback()
  } else {
    if (!value) {
      return callback(new Error('密码不能为空'));
    }
    // 口令应包括数字、小写字母、大写字母、特殊符号4类中至少3类
    let reg = new RegExp('(?=.*[0-9])(?=.*[A-Z])(?=.*[a-z])(?=.*[^a-zA-Z0-9]).{8,15}')
    if (!reg.test(value)) {
      return callback(new Error('密码长度8-15位，包括数字、大小写字母、特殊符号的组合'))
    }

    if(validateKey(value)) {
      return callback(new Error('密码不允许出现键盘排序'))
    }
    callback()
  }
}

// 密码中不得包含用户名的形似形变
export function uNameAndPwd(name, password) {
  if(!name) {
    return false;
  }
  let reName = name.replace(/0/g, 'Q').replace(/o/g, 'Q').replace(/O/g, 'Q')
    .replace(/1/g, 'l').replace(/!/g, 'l').replace(/i/g, 'l')
    .replace(/6/g, 'b').replace(/d/g, 'b')
    .replace(/2/g, 'z').replace(/Z/g, 'z')
    .replace(/g/g, 'y').replace(/9/g, 'y')
    .replace(/C/g, '(').replace(/c/g, '(')
    .replace(/S/g, '$').replace(/s/g, '$')
    .replace(/p/g, 'q').replace(/P/g, 'R').replace(/f/g, 't').replace(/a/g, '@')
    .replace(/J/g, 'L').replace(/m/g, 'n').replace(/U/g, 'V');
  let rePwd = password.replace(/0/g, 'Q').replace(/o/g, 'Q').replace(/O/g, 'Q')
    .replace(/1/g, 'l').replace(/!/g, 'l').replace(/i/g, 'l')
    .replace(/6/g, 'b').replace(/d/g, 'b')
    .replace(/2/g, 'z').replace(/Z/g, 'z')
    .replace(/g/g, 'y').replace(/9/g, 'y')
    .replace(/C/g, '(').replace(/c/g, '(')
    .replace(/S/g, '$').replace(/s/g, '$')
    .replace(/p/g, 'q').replace(/P/g, 'R').replace(/f/g, 't').replace(/a/g, '@')
    .replace(/J/g, 'L').replace(/m/g, 'n').replace(/U/g, 'V');
  if (rePwd.indexOf(reName) != -1) {
    return true
  }
  return false
}

// 密码不得包含用户名
export function containsName(name, password) {
  if(!name) {
    return false;
  }
  let pwdTemp = password.toLowerCase()
  let nameTemp = name.toLowerCase()
  if(pwdTemp.indexOf(nameTemp) != -1) {
    return true
  }
  return false
}

// 返回下拉列表  针对列表e 中对象key为value、text的处理
const getOptions = (e, showall) => {
  let arr = []
  if (showall === true) {
    arr.push({
      value: '',
      label: '==全部=='
    })
  }
  e.forEach(item => {
    arr.push({
      value: item.value,
      label: item.text
    })
  })
  return arr
}

// 返回下拉列表 指定lable和value的字段
const optionsSwitch = (e, v, k, showall) => {
  let arr = []
  if (showall === true) {
    arr.push({
      value: '',
      label: '==全部=='
    })
  }
  e.forEach(item => {
    arr.push({
      value: item[v] + '',
      label: item[k]
    })
  })
  return arr
}
const optionsSwitchMulti = (e, [v, k, i], showall) => {
  let arr = []
  if (showall === true) {
    arr.push({
      value: '',
      label: '==全部=='
    })
  }
  e.forEach(item => {
    arr.push({
      value: item[v],
      label: item[k],
      info: item[i]
    })
  })
  return arr
}

/**
 * 根据value获取下拉列表的text值
 * @param l
 * @param e
 */
const getOptionText = (l, e) => {
  let retuenText = ''
  l.forEach(item => {
    if (e === item.value) {
      retuenText = item.label
    }
  })
  return retuenText
}

/**
 * 根据value获取下拉列表的额外ingo值
 * @param l
 * @param e
 * @returns {string}
 */
const getOptionInfo = (l, e) => {
  let retuenText = ''
  l.forEach(item => {
    if (e === item.value) {
      retuenText = item.info || ''
    }
  })
  return retuenText
}

/**
 * 用于:key值重复页面报错解决
 * 用法：  :key="this.$utils.guid()"
 */
const getGuid = () => {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
    let r = Math.random() * 16 | 0
    let v = c === 'x' ? r : (r & 0x3 | 0x8)
    return v.toString(16)
  })
}

/**
 * 获取[minNum,minNum]间随机值
 * @param minNum
 * @param maxNum
 * @returns {number}
 */
const randomNum = (minNum, maxNum) =>{
  return parseInt(Math.random()*(maxNum-minNum+1)+minNum,10)
}

// 自定义增加class类方法
const addClass = (ele, name) => {
  if (name) {
    let classArr = ele.className.split(' ')
    let index = classArr.indexOf(name)
    if (index >= 0) return
    // 判断该dom有没有class，有则在原class基础上增加，无则直接赋值
    ele.className ? ele.className = ele.className + '' + name : ele.className = name
  }
}

// 自定义删除class类方法
const removeClass = (ele, name) => {
  // 将className属性转为数组
  let classArr = ele.className.split(' ')
  let index = classArr.indexOf(name)
  // 将符合条件的class类删除
  if (index > -1) classArr.splice(index, 1)
  ele.className = classArr.join(' ')
}

// 通过class获取元素
const getByClass = (oParent, sClass) => {
  let aResult=[];
  let aEle=document.getElementsByTagName('*')
  // console.log(aResult)
  for(let i=0;i<aEle.length;i++){
    if(aEle[i].className === sClass) {
      aResult.push(aEle[i])
    }
  }
  return aResult
}

const isEmptyObject = (obj) => {
  return JSON.stringify(obj) === '{}'
}

/**
 *  queryFields中类型为Select的 按照prop过滤  修改 $filed 中options 属性 值为 data
 * @param $filed
 * @param prop
 * @param data
 */
const $setField = ($filed, prop, data) => {
  $filed.filter(x => x['prop'] === prop)[0].options = data
}

/**
 * 相对页面做内滑动时某个元素的高度计算,多用于table
 * @param params
 * @returns {number}
 */
const $resizeElementH = (params) => {
  console.log()
  let ch = document.documentElement.clientHeight || document.body.clientHeight  // 屏幕高度
  let cw = document.documentElement.clientWidth || document.body.clientWidth  // 屏幕宽度
  let header = 0
  if (cw < 1281) {
    header = 55 + 30 + (Vue.prototype.$cfg.ISSHOWMENUTAGS ? 35 : 0)
  } else {
    header = 65 + 40 + (Vue.prototype.$cfg.ISSHOWMENUTAGS ? 30 : 0)
  }
  let H = 0
  if(typeof params === 'array') {
    params.forEach(item => {
      H += item.$el.offsetHeight
    })
  } else if(typeof params === 'object') {
    H = params.$el.offsetHeight
  }
  return ch - header - H
}

/**
 * 内部元素高度处理
 * @param ch
 *        父元素高度
 * @param params
 *        子元素对象或数组
 * @returns {number}
 */
const $resizeInnerElementH = (ch, params) => {
  // console.log(ch)
  // let ch = parent.$el.offsetHeight  // 屏幕高度
  // let cw = document.documentElement.clientWidth || document.body.clientWidth  // 屏幕宽度
  let header = 10
  // if (cw < 1281) {
  //   header = 55 + 30 + 35
  // } else {
  //   header = 65 + 40 + 30
  // }
  let H = 0
  if(typeof params === 'array') {
    params.forEach(item => {
      H += item.$el.offsetHeight
    })
  } else if(typeof params === 'object') {
    H = params.$el.offsetHeight
  }
  return ch - header - H
}

/**
 * 相对页面做内滑动时某个元素的高度计算,多用于table
 * @param params
 * @returns {number}
 */
const $resizeModalElementH = (params) => {
  let ch = document.documentElement.clientHeight || document.body.clientHeight  // 屏幕高度
  let H = 0
  if(typeof params === 'array') {
    params.forEach(item => {
      H += item.$el.offsetHeight
    })
  } else if(typeof params === 'object') {
    H = params.$el.offsetHeight
  }
  return ch*0.7 - H - (60)
}
const $filterDomH = () => {
  let ch = document.documentElement.clientWidth || document.body.clientWidth  // 屏幕高度
  if (ch < 1281) {
    return 55 + 30 + 35
  } else {
    return 65 + 40 + 30
  }
}

/**
 * 对象数组去重方法
 * @param jsonarray
 * @returns {jsonarray}
 */
const objArrayDuplication = (jsonarray) => {
  return jsonarray.filter((x, index, self) => {
    let arrKeys = []
    jsonarray.forEach((item, i) => {
      arrKeys.push(item.key)
    })
    return arrKeys.indexOf(x.key) === index
  })
}

// 数组对象深克隆
const fnDeepClone = (obj) => {
  let result = typeof obj.splice === 'function'?[]:{}
  let key
  if (obj && typeof obj === 'object'){
    for (key in obj ){
      if (obj[key] && typeof obj[key] === 'object'){
        result[key] = fnDeepClone(obj[key]) //如果对象的属性值为object的时候，递归调用deepClone，即再把某个值对象复制一份到新的对象的对应值中
      }else{
        result[key] = obj[key] //如果对象的属性值不为object的时候，直接复制参数对象的每一个键/值到新对象对应的键/值中
      }
    }
    return result
  }
  return obj
}

// 删除JSON数组中的某一个元素
// _arr:需要删除的JSON数组  _obj:需要删除的元素
function removeArray(_arr, _obj) {
  let length = _arr.length
  for (let i = 0; i < length; i++) {
    if (_arr[i] === _obj) {
      if (i === 0) {
        _arr.shift()
        return _arr
      } else if (i === length - 1) {
        _arr.pop()
        return _arr
      } else {
        _arr.splice(i, 1)
        return _arr
      }
    }
  }
}

// 导出按钮遍历方法
const exportBtnFunction = (column, need) => {
  let exportData = []
  if (need) {
    column.forEach(item => {
      for (let i in need) {
        if (need[i] === item.key) {
          exportData.push({
            [item.key]: item.title
          })
        }
      }
    })
  } else {
    column.forEach(item => {
      exportData.push({
        [item.key]: item.title
      })
    })
  }
  return JSON.stringify(exportData)
}

// 导出时拼接URL的方法
const urlCharacterSplicing = (jsondata) => {
  let str = ''
  for (let i in jsondata) {
    str += `&${i}=${encodeURIComponent(jsondata[i])}`
  }
  return str
}

// 判断是否为JSON格式数据
const isJSON = (str) => {
  try {
    JSON.parse(str)
    return true
  } catch (e) {
    return false
  }
}

export default {
  getGuid,
  fnDeepClone,
  getOptions,
  getOptionText,
  getOptionInfo,
  optionsSwitch,
  optionsSwitchMulti,
  randomNum,
  getByClass,
  addClass,
  removeClass,
  checkSpecialString,
  isEmptyObject,
  objArrayDuplication,
  $setField,
  $filterDomH: $filterDomH(),
  $resizeElementH,
  $resizeInnerElementH,
  $resizeModalElementH,
  removeArray,
  exportBtnFunction,
  urlCharacterSplicing,
  isJSON
}

